
import { _decorator, Component, Node, Vec3, v3 } from 'cc';
import LevelColler from '../../MainScene/Script/LevelColler';
import { Role } from '../../Role/Script/Role';
import EventManager from '../../Script/Common/EventManager';
import GameConfig from '../../Script/GameSpecial/GameConfig';
import { EventType } from '../../Script/GameSpecial/GameEventType';
import { GlobalEnum } from '../../Script/GameSpecial/GlobalEnum';
const { ccclass, property } = _decorator;

@ccclass('Trapper')
export class Trapper extends LevelColler {

    protected initSub() {
        this.initAABB();
        this.initState();
    }
    protected resetSub() {
        this.resetAABB();
        this.resetDirtyFlags();
        this.resetState();
    }
    protected onEvents() {
        this.on(EventType.LevelEvent.dropTrapper, this.onDropTrapper, this);
    }
    protected registAllCustomUpdate() {
        this.registCustomUpdate(State.fly, this.stepFly);
    }
    protected setData(data: { role: Role, speed: Vec3 }) {
        this.speed.set(data.speed);
        this.atkRole = data.role;
        this.scale = data.role.roleScale;
        let s = this.scale * 50;
        this.node.setScale(s, s, s);
        let p = data.role.node.position;
        this.node.setPosition(p.x, this.scale, p.z);
        this.cachePos.set(this.node.position);
        this.setDirtyFlags(GlobalEnum.DirtyType.aabb);
        this.node.eulerAngles = v3();
        this.visible = true;
        this.enterCustomUpdateState(State.fly);
    }

    public visible: boolean = true;
    protected atkRole: Role;
    protected speed: Vec3 = null;
    protected cachePos: Vec3 = null;
    protected scale: number = 1;
    protected initState() {
        this.visible = true;
        this.atkRole = null;
        this.speed = new Vec3();
        this.cachePos = new Vec3();
        this.scale = 1;
        this.setDirtyFlags(GlobalEnum.DirtyType.aabb);
    }
    protected resetState() {
        this.visible = true;
        this.atkRole = null;
        this.scale = 1;
        this.setDirtyFlags(GlobalEnum.DirtyType.aabb);
    }

    /**更新碰撞包围盒 */
    protected processDirty() {
        if (this.aabbDirty) {
            this.aabbDirty = false;

            let s = this.scale;
            this._aabb.xMin = s * this.minVert.x + this.node.position.x;
            this._aabb.xMax = s * this.maxVert.x + this.node.position.x;
            this._aabb.xScope = (this._aabb.xMax - this._aabb.xMin) * 0.5;

            this._aabb.yMin = this.minVert.y + this.node.position.y;
            this._aabb.yMax = this.maxVert.y + this.node.position.y;
            this._aabb.yScope = this._aabb.yMax - this._aabb.yMin;

            this._aabb.zMin = s * this.minVert.z + this.node.position.z;
            this._aabb.zMax = s * this.maxVert.z + this.node.position.z;
            this._aabb.zScope = (this._aabb.zMax - this._aabb.zMin) * 0.5;

            this._aabb.xCenter = this._aabb.xMin + this._aabb.xScope;
            this._aabb.yCenter = this._aabb.yMin + this._aabb.yScope * 0.5;
            this._aabb.zCenter = this._aabb.zMin + this._aabb.zScope;

            this._center.x = this._aabb.xCenter;
            this._center.y = this._aabb.yCenter;
            this._center.z = this._aabb.zCenter;

        }
    }

    /**爆炸 */
    public boom(audio: boolean = true) {
        if (!this.visible) return;
        this.visible = false;
        this.emit(EventType.LevelEvent.addBoomEffect, {
            p: this.node.position,
            s: this.atkRole.roleScale,
        });
        this.emit(EventType.LevelEvent.addParticle, {
            n: "BoomParticle",
            p: this.node.position,
            s: this.scale,
        });
        if (audio) {
            this.emit(EventType.Common.AudioEvent.playEffect, GlobalEnum.AudioClip.atkTrapperBoom);
        }
    }

    public onColled(other: LevelColler) {
        if (this.atkRole.Id == other.Id) {
            return;
        }
        if (other.collerType == GlobalEnum.CollerType.role && (other.invicible || !other.isAlive)) return;
        this.boom();
        this.hitSuccess(other);
    }

    protected hitSuccess(other) {
        this.atkRole.hitSuccess(other);
        other.beHit(this);
        if (this.atkRole.isPlayer && other.collerType == GlobalEnum.CollerType.barrier) {
            switch (other.breakAudioType) {
                case 0: {
                    this.audioClip = GlobalEnum.AudioClip.breakWood;
                    break;
                }
                case 1: {
                    this.audioClip = GlobalEnum.AudioClip.breakStones;
                    break;
                }
                case 2: {
                    this.audioClip = GlobalEnum.AudioClip.breakMetal;
                    break;
                }
            }
        }
    }
    protected audioClip: string = null;
    public processHitAudio() {
        if (!!this.audioClip && this.atkRole.disToPlayerSqr < GameConfig.GameRule.enemyAudioScopeSqr) {
            EventManager.emit(EventType.Common.AudioEvent.playEffect, this.audioClip);
        }
        this.audioClip = null;
    }


    /**飞行过程中 */
    protected stepFly(dt: number) {
        this.speed.y -= GameConfig.GameRule.trapperGravity * dt;//todo:重力加速度待定
        this.cachePos.x += this.speed.x * dt;
        this.cachePos.y += this.speed.y * dt;
        this.cachePos.z += this.speed.z * dt;
        if (this.cachePos.y <= 0) {
            this.cachePos.y = 0;
            this.enterCustomUpdateState(State.stop);
        }
        this.node.setPosition(this.cachePos);
        this.setDirtyFlags(GlobalEnum.DirtyType.aabb);
    }


    protected onDropTrapper(roleId: number) {
        if (!this.visible) return;
        if (roleId == this.atkRole.Id) {
            this.boom(false);
            this.emit(EventType.LevelEvent.removeTrapper, this);
        }
    }
}

enum State {
    fly,
    stop,
    boom,
}
